/**
 * 通用表单验证类regClass.js
 *
 * @create 2012/06 [@fzxa] www.nonb.cn
 * @editor [@author] [yy-mm-dd H:i:s]
 * @version v1.0 $Id$
 */
 
//String.prototype.trim.call(str);
//str.trim().toString();
String.prototype.trim = function(){   return this.replace(/(^\s*)|(\s*$)/g, ""); }
String.prototype.format=function(){
if(arguments.length==0) return this;
for(var s=this, i=0; i<arguments.length; i++)
s=s.replace(new RegExp("\\{"+i+"\\}","g"), arguments[i]);
return s;
};

var formValidate = function(params, formName, debug) {
 
        var me          = this;
        this.doc        = document;
        this.formName   = formName;
        this.params     = params;
        this.formNameObj;
        this.formParams = [];
        this.success    = true;
        this.formTips; //tips提示框
        this.elemReg    = {}; //存储验证规则
        this.status     = false; //验证状态
        this.passwordVal;
        this.debug      = debug || false;
 
        this.init(me);
    }
 
formValidate.prototype = {
 
    _$: function(elem) {
        if (elem.length <= 0) {
            return false;
        }
        return this.doc.getElementById(elem);
    },
 
    /**
     * IE object debug
     * @param  {object} myObject 
     * @return {string}
     */
    var_dump: function(myObject) {
        var s = "";
        for (var property in myObject) {
            s = s + "\n " + property + ": " + myObject[property];
        }
 
        document.write('<pre>' + s + '</pre>');
    }
 
}
 
/**
 * formValidate初始化
 * @param  {object} me 
 * @return {null}   
 */
formValidate.prototype.init = function(me) {
    this.selectForm(me);
}
 
/**
 * 选择验证表单,绑定事件
 * @param  {object} me 
 * @return {null}
 */
formValidate.prototype.selectForm = function(me) {
 
    //this.formNameObj = this.doc.getElementById(this.formName);
 
    for (var formElement in this.params) {
 
        var element = this.doc.getElementsByName(formElement);
        //绑定click事件
        for (var i = 0, count = element.length; i < count; i++) {
            var elem = element[i]; //元素
            this.elemReg[formElement] = this.params[formElement]; //验证条件
 
            if(elem.name =='password'){
                this.addEvent(elem, 'input', function(elem) {
                    me.showTips(elem);
                   // me.tipsPasswordStrength(elem);
                });
            }
 
            this.addEvent(elem, 'focus', function(elem) {
                //me.inputFocus(elem,true);
                me.showTips(elem);
            });
 
            this.addEvent(elem, 'blur', function(elem) {
               // me.inputFocus(elem,false);
                me.checkElement(elem);
            });
        }
    };
 
}
 
/**
 * 判断密码强度
 * @param  {object} elem 
 * @return {int}  返回密码强度级别 1：弱, 2中, 3强    
 */
formValidate.prototype.checkPasswordStrength = function(elem){
 
    var element = elem.srcElement || elem.target;
    var pwd = element.value;
 
    if (pwd == null || pwd == '') {
        return 0;
    } else {
        var level = checkStrong(pwd);
        level == 0 ? level = 1 : level > 3 ? level = 3 : level;
        return level;
    }
    //bitTotal函数  
    function CharMode(iN) {
        if (iN >= 48 && iN <= 57) //数字  
            return 1;
        if (iN >= 65 && iN <= 90) //大写  
            return 2;
        if (iN >= 97 && iN <= 122)//小写  
            return 4;
        else
            return 8;
    }
     
    //计算密码模式  
    function bitTotal(num) {
        var modes = 0;
        for (i = 0; i < 3; i++) {
            if (num & 1) modes++;
            num >>>= 1;
        }
        return modes;
    }
    //返回强度级别  
    function checkStrong(sPW) {
        if (sPW.length <= 3) return 0; //密码太短  
        var Modes = 0;
        for (i = 0; i < sPW.length; i++) {
            //密码模式  
            Modes |= CharMode(sPW.charCodeAt(i));
        }
        return bitTotal(Modes);
    }
}
 
/**
 * 显示密码级别在tips中
 * @param  {obejct} elem 选择元素
 * @return {null}      
 */
formValidate.prototype.tipsPasswordStrength = function(elem){
    var level = this.checkPasswordStrength(elem);
    var tags = this.getMsgTags(elem);
    var tagsHtml = '密码强度:';
 
    switch(level){
        case 1:
            tags.msgPwd.innerHTML = tagsHtml+'<span class="pswdcheck-1"> </span><b>弱</b>';
            break;
        case 2:
            tags.msgPwd.innerHTML = tagsHtml+'<span class="pswdcheck-2"> </span><b>中</b>';
            break;
        case 3:
            tags.msgPwd.innerHTML = tagsHtml+'<span class="pswdcheck-3"> </span><b>强</b>';
            break;
        default:
            tags.msgPwd.innerHTML = tagsHtml+'<span class="pswdcheck-1"> </span><b>弱</b>';
            break;
    }
}
 
/**
 * focus加边框
 * @param  {object} elem 选择元素
 * @param  {boolean} bool 显示隐藏
 * @return {null}      
 */
formValidate.prototype.inputFocus = function(elem,bool){
    var element = elem.srcElement || elem.target;
    var err;
    //this.getSuccessTags(elem).style.display = 'none';
 
    if(element.className == 'ui-input error'){
        err = ' error';
    }else{
        err = '';
    }
 
    if(bool == true){
        element.className = 'ui-input focus' + err;
    }else{
        element.className = 'ui-input' + err;
    }
 
}
 


/**
 * 获取msg子节点
 * @param  {object} elem 选择元素
 * @return {object}      返回节点
 */
formValidate.prototype.getTipTags = function(elem){
  
    var element = elem.srcElement || elem.target;
 
    var elementChildNodes = element.parentNode.childNodes;
    var msg; //tips容器 
    for (var i = 0,childNodesCount = elementChildNodes.length; i < childNodesCount; i++) {
        if(elementChildNodes[i].nodeType == 3) {//文本text 
            continue;
        }else{
        	if(elementChildNodes[i].className.indexOf('ui-tiptext-container') >= 0){
        		msg = elementChildNodes[i];
        	} 
        }
    };
    
    return msg;
}

/**
 * 获取msg子节点
 * @param  {object} elem 选择元素
 * @return {object}      返回节点
 */
formValidate.prototype.getMsgTags = function(elem){
 
    var resultHtmlTags = {};
    var element = elem.srcElement || elem.target;
 
    var elementChildNodes = element.parentNode.childNodes;
    var msg; //tips容器
    var msgArr = [];
    for (var i = 0,childNodesCount = elementChildNodes.length; i < childNodesCount; i++) {
        if(elementChildNodes[i].nodeType == 3) {//文本text 
            continue;
        }else{
        	console.info(elementChildNodes[i].className);
            msgArr.push(elementChildNodes[i]);
        }
    };
    msg = msgArr[3];
 
    var msgChildNodes = msg.childNodes;
    var msgCon; //con容器
    var msgConArr = [];
    for (var i = 0,msgChildNodesCount = msg.childNodes.length; i < msgChildNodesCount; i++) {
        if(msgChildNodes[i].nodeType == 3) {
            continue;
        }else{
            msgConArr.push(msgChildNodes[i]);
        }
    };
    msgCon = msgConArr[1];
 
    if(element.name == 'password'){
        msgCon = msgConArr[2];
        resultHtmlTags.msgPwd = msgConArr[1];
    }
 
    resultHtmlTags.msg = msg;
    resultHtmlTags.msgCon = msgCon;
    console.info(resultHtmlTags);
    return resultHtmlTags;
}
 
/**
 * 成功提示
 * @param  {object} elem 选择元素
 * @return {object}      success元素
 */
formValidate.prototype.getSuccessTags = function(elem){
 
    var element = elem.srcElement || elem.target;
    var elementChildNodes = element.parentNode.childNodes;
    var sTag; //tips容器
 
    for (var i = 0,childNodesCount = elementChildNodes.length; i < childNodesCount; i++) {
        if(elementChildNodes[i].nodeType == 3) {
            continue;
        }else{
            if(elementChildNodes[i].nodeName == 'SPAN'){
                sTag = elementChildNodes[i];
            }
        }
    };
 
    return sTag;
}
 
/**
 * 定位tips并且显示
 * @parmas {object} elem 元素
 */
formValidate.prototype.showTips = function(elem) {
	
    var element = elem.srcElement || elem.target;
    var elemValue = element.value;
    var elemName = element.name; 
    var tipsCon = this.elemReg[elemName].tips;
 
    var msg = this.getTipTags(elem); 
 
    if(elemValue.length == 0){
        msg.className = 'ui-tiptext-container ui-tiptext-container-message';
        msg.style.display = 'block';
        msg.innerHTML = '<div class="ui-tiptext-arrow ui-tiptext-arrowleft"><em>◆</em><span>◆</span></div><p class="ui-tiptext"><i class="ui-tiptext-icon iconfont" title="提示">&#xF046;</i>'+tipsCon+'</p>';
    }
}

/**
 * 定位tips并且显示
 * @parmas {object} elem 元素
 */
formValidate.prototype.showEleTips = function(element) {
	 
    var elemValue = element.value;
    var elemName = element.name; 
    var tipsCon = this.elemReg[elemName].tips;
 
    var msg = this.getTipTags(elem); 
 
    if(elemValue.length == 0){
        msg.className = 'ui-tiptext-container ui-tiptext-container-message';
        msg.style.display = 'block';
        msg.innerHTML = '<div class="ui-tiptext-arrow ui-tiptext-arrowleft"><em>◆</em><span>◆</span></div><p class="ui-tiptext"><i class="ui-tiptext-icon iconfont" title="提示">&#xF046;</i>'+tipsCon+'</p>';
    }
}
/**
 * 定位tips并且显示
 * @parmas {object} elem 元素
 */
formValidate.prototype.showErrorTips = function(elem,errorTips) {
	 
    var msg = this.getTipTags(elem); 
  
        msg.className = 'ui-tiptext-container ui-tiptext-container-error';
        msg.style.display = 'block';
        msg.innerHTML = '<div class="ui-tiptext-arrow ui-tiptext-arrowleft"><em>◆</em><span>◆</span></div><p class="ui-tiptext"><i class="ui-tiptext-icon iconfont" title="提示">&#xF045;</i>'+errorTips+'</p>';
    
}
/**
 * 检查表单数据
 * @param  {object} elem 选择元素
 * @return {boolean}      返回状态
 */
formValidate.prototype.checkElement = function(elem) {
 
    var element = elem.srcElement || elem.target;
    var elemValue = element.value;
    var elemName = element.name;
 
    var elemReg = this.elemReg[elemName].regexp;
    var elemTip = this.elemReg[elemName].tips;
    //自定义验证
    var mycheck = this.elemReg[elemName].check;
    //获取tip
    var msg = this.getTipTags(elem);
 
    var regExs = this.regexs(); 
 
    //验证状态
    var status = true;
    for (var e in elemReg) {
 
        //console.log(elem);
        //console.log(elemReg[elem]);
    	if(elemName == 'confirmPassword'){
            var pwdVal = this.doc.getElementsByName('password')[0].value;
            if(elemValue !== pwdVal){
            	 elemTip = '两次输入的密码不一致';
            	 msg.className = 'ui-tiptext-container ui-tiptext-container-error';
                 msg.style.display = 'block';
                 msg.innerHTML = '<div class="ui-tiptext-arrow ui-tiptext-arrowleft"><em>◆</em><span>◆</span></div><p class="ui-tiptext"><i class="ui-tiptext-icon iconfont" title="提示">&#xF045;</i>'+elemTip+'</p>';
             
                status = false;
                this.formParams[elemName] = false;
            }
        }else{
        	if (!regExs[e].test(elemValue)) {
        		elemTip = elemReg[e]; 
                //msg.className = 'ui-tiptext-container ui-tiptext-container-error';
               // msg.style.display = 'block';
                //msg.innerHTML = '<div class="ui-tiptext-arrow ui-tiptext-arrowleft"><em>◆</em><span>◆</span></div><p class="ui-tiptext"><i class="ui-tiptext-icon iconfont" title="提示">&#xF045;</i>'+elemTip+'</p>';
        	   this.showErrorTips(elem,elemTip);
               status = false;
               this.formParams[elemName] = false;
               //this.success = false;
           } 
        }
    	if(!status){
    		break;
    	}
        
    }
 
    //TODO如果有自定义函数并且简单验证通过则继续验证
    if(mycheck !== undefined && status == true){
    	for (var e in mycheck) {
    		var elemTip = mycheck[e]; 
    		var result = eval(e+'()');
    		alert(result);
    		if(!result){
                status = false;
                elemTip = elemTip.format(elemValue); 
                this.formParams[elemName] = false; 
      			this.showErrorTips(elem,elemTip);
    		}
    	}
    }
    //TODO 判断单个验证状态
    if(status == true){
    	msg.className = 'ui-tiptext-container fn-hide';
    	msg.innerHTML = '';
    }
}
 
/**
 * 正则验证规则
 * @return {object} 验证规则
 */
formValidate.prototype.regexs = function() {
 
    var $_regexs = {
        require: /.+/,
        password1: /[a-zA-z]{1}[a-zA-z0-9_,]{5,15}/,
        password: /^(\w){6,16}$/,
        email: /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/,
        phone: /^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$/,
        mobile: /^((\(\d{2,3}\))|(\d{3}\-))?((13\d{9})|(15[389]\d{8}))$/,
        url: /^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"])*$/,
        ip: /^(0|[1-9]\d?|[0-1]\d{2}|2[0-4]\d|25[0-5]).(0|[1-9]\d?|[0-1]\d{2}|2[0-4]\d|25[0-5]).(0|[1-9]\d?|[0-1]\d{2}|2[0-4]\d|25[0-5]).(0|[1-9]\d?|[0-1]\d{2}|2[0-4]\d|25[0-5])$/,
        currency: /^\d+(\.\d+)?$/,
        number: /^\d+$/,
        zip: /^[1-9]\d{5}$/,
        qq: /^[1-9]\d{4,8}$/,
        english: /^[A-Za-z]+$/,
        chinese: /^[\u0391-\uFFE5]+$/,
        username: /[a-zA-z]{1}[a-zA-z0-9_]{3,15}/,
        integer: /^[-\+]?\d+$/,
        'double': /^[-\+]?\d+(\.\d+)?$/
    };
 
    return $_regexs;
}
 
/**
 * 元素事件绑定
 * @param {object} elem 元素
 * @param {string} evtType 触发事件
 * @param {function} func 触发函数
 */
formValidate.prototype.addEvent = function(elem, evtType, func) {
     
    if(/msie/i.test(navigator.userAgent)){
        if(evtType == 'input'){
            evtType = 'propertychange';
        }
    }
 
    if (elem.addEventListener) {
        elem.addEventListener(evtType, func, false);
    } else if (elem.attachEvent) {
        elem.attachEvent("on" + evtType, func);
    } else {
        elem["on" + evtType] = func;
    }
 
}




